<!--
    by: yuanbiao 2020年09月17日
    name: x-video
    notes:
-->
<template>
  <div
    ref="xVideo"
    :class="[
      `${prefixCls}`, `${prefixCls}-${size}`,
      {
        [`${prefixCls}-error`]:statusCtrl.error,
        [`${prefixCls}-hastoolsbar`]:!statusCtrl.autoHideToolsbar,
        [`${prefixCls}-${fullscreenActive.name}`]:statusCtrl.isFullscreen
      }
    ]"
    @mousemove="toolsbarToggle" @touchstart="toolsbarToggle"
    @keydown.prevent.stop="keydownHandler"
    tabindex="1"
  >
    <video ref="video" :class="`${prefixCls}__video`"
      :x5-playsinline="true"
      :playsinline="true"
      :webkit-playsinline="true"
      :controls="false"
      :autoplay="statusCtrl.autoplay"
      :preload="statusCtrl.preload"
      :poster="videoActive.poster"
      crossOrigin="anonymous"
      @play="playCallback"
      @abort="abortCallback"
      @canplay="canplayCallback"
      @pause="pauseCallback"
      @ended="endedCallback"
      @loadedmetadata="loadedmetadataCallback"
      @timeupdate="timeupdateCallback"
      @durationchange="durationchangeCallback"
      @waiting="waitingCallback"
      @error="errorCallback"
    >
      <source :src="statusCtrl.currentSrc" :type="videoActiveType" />
      <track default
        :src="videoActiveSubtitle.value"
        :label="videoActiveSubtitle.label"
        :kind="videoActiveSubtitle.kind"
        :srclang="videoActiveSubtitle.srclang || 'zh'"
        :key="videoActiveSubtitle.value || `r_${Math.random()}`"
      />
    </video>
    <div v-if="videoActiveSubtitle.type==='srt'" :class="`${prefixCls}__subtitle`">
      <template v-for="(v,i) in srtSubtitleData">
        <div v-if="statusCtrl.videoCurrentTime >= v.startTime &&  statusCtrl.videoCurrentTime < v.endTime"
          v-html="v.text"
          :key="i"
        ></div>
      </template>
    </div>
    <div :class="`${prefixCls}__mask`" @click="togglePlay">
      <i v-show="statusCtrl.isLoading && statusCtrl.currentSrc" class="xvu-iconfont xvu-spinner"></i>
    </div>
    <transition enter-active-class="animated fadeInDown" leave-active-class="animated fadeOutUp">
      <div v-show="statusCtrl.toolsbarShow || !statusCtrl.autoHideToolsbar" :class="`${prefixCls}__title`">
        <span v-if="statusCtrl.videoActiveIndex > -1">
          {{videoActive.label || `视频 ${statusCtrl.videoActiveIndex + 1}`}}
        </span>
      </div>
    </transition>
    <div v-show="showMenu"
      :class="[`${prefixCls}__menu`, statusCtrl.collapsePlaylist ? `${prefixCls}__menu-collapse` : '']"
    >
      <div :class="`${prefixCls}__menu_head`">
        <div class="fl"><i class="xvu-iconfont xvu-list"></i>播放列表</div>
        <div class="fr" v-show="statusCtrl.showMenuDelete" @click="menuDeleteClick">
          <i class="xvu-iconfont xvu-delete" title="清空列表"></i>
        </div>
      </div>
      <div :class="`${prefixCls}__menu_body`" @drop.prevent="drop2playlistHandler" @dragover.prevent>
        <div v-for="(v, i) in allVideoList" :key="i" @click="playItem(i)"
          :class="[`${prefixCls}__menu_item`, {active: i === statusCtrl.videoActiveIndex}]"
        >
          <div :class="`${prefixCls}__menu_item_label`">
            <div :class="`${prefixCls}__menu_item_label_title`">{{v.label || `视频 ${i + 1}`}}</div>
            <div :class="`${prefixCls}__menu_item_label_duration`">{{v.duration | formatTime}}</div>
          </div>
          <div :class="`${prefixCls}__menu_item_poster`" v-if="statusCtrl.showMenuPoster">
            <img :src="v.poster || undefined"
              @error="onImgError"
            />
          </div>
        </div>
        <p v-if="allVideoList.length===0" :class="`${prefixCls}__menu_body-nodata`">暂无数据</p>
      </div>
      <div :class="`${prefixCls}__menu_btn`" @click="menuBtnClick">
        <i :class="[
          'xvu-iconfont',
          statusCtrl.collapsePlaylist ? 'xvu-collapse-right' : 'xvu-collapse-left'
        ]"></i>
      </div>
    </div>
    <transition enter-active-class="animated fadeInUp" leave-active-class="animated fadeOutDown">
      <div v-show="statusCtrl.toolsbarShow || !statusCtrl.autoHideToolsbar" :class="`${prefixCls}__toolsbar`">
        <div :class="`${prefixCls}__toolsbar_left`">
          <div v-show="statusCtrl.fullscreenable" :class="`${prefixCls}__toolsbar_fullscreen`"
            @mouseenter="togglePoptip('fullscreenlist')"
            @mouseleave="togglePoptip('')"
          >
            <span class="label">
              <i :class="['xvu-iconfont', statusCtrl.isFullscreen ? fullscreenActive.icons[1] : fullscreenActive.icons[0]]"
                :title="statusCtrl.isFullscreen ? '还原' : fullscreenActive.label" @click="toggleFullscreen"
              ></i>
            </span>
            <x-video-poptip v-show="!statusCtrl.isFullscreen && statusCtrl.poptipActive==='fullscreenlist'">
              <div
                v-for="(v,i) in fullscreenListActive" :key="i"
                :class="['x-video-poptip-item']"
                @click="fullscreenItemClick(v,i)"
              >
                <i :class="['xvu-iconfont', statusCtrl.isFullscreen ? v.icons[1] : v.icons[0]]"
                  :title="statusCtrl.isFullscreen ? '还原' : v.label"
                ></i>
              </div>
            </x-video-poptip>
          </div>
          <div :class="`${prefixCls}__toolsbar_volume`" @click.stop>
            <i :class="['xvu-iconfont', statusCtrl.videoVolume ? 'xvu-audio' : 'xvu-muted']"
              title="音量" @click.stop="togglePoptip('volumebar')"
            ></i>
            <x-video-poptip v-show="statusCtrl.poptipActive==='volumebar'">
              <x-video-progress ref="volumebarProgress" vertical @change="volumebarProgressChange"></x-video-progress>
            </x-video-poptip>
          </div>
          <i :class="[`${prefixCls}__playorder`, 'xvu-iconfont', playOrderActive.icon]" @click="playOrderChange">
            <transition enter-active-class="animated fadeIn" leave-active-class="animated fadeOut">
              <span v-show="statusCtrl.playOrderTextShow" :class="`${prefixCls}__playorder_label`">
                {{playOrderActive.label}}
              </span>
            </transition>
          </i>
        </div>
        <div :class="`${prefixCls}__toolsbar_middle`">
          <i class="xvu-iconfont xvu-prev" title="上一首" @click="prev"></i>
          <i v-show="statusCtrl.isPlaying" class="xvu-iconfont xvu-pause" title="暂停" @click="pause"></i>
          <i v-show="!statusCtrl.isPlaying" class="xvu-iconfont xvu-play" title="播放" @click="play"></i>
          <i class="xvu-iconfont xvu-next" title="下一首" @click="next"></i>
        </div>
        <div :class="`${prefixCls}__toolsbar_right`">
          <div
            v-show="videoActiveUrls.length"
            :class="`${prefixCls}__toolsbar_clarity`"
          >
            <span class="label" @click.stop="togglePoptip('clarity')">
              {{(videoActiveUrls[statusCtrl.videoUrlActiveIndex] || {}).label || '清晰度'}}
            </span>
            <x-video-poptip v-show="statusCtrl.poptipActive==='clarity'">
              <div
                v-for="(v,i) in videoActiveUrls" :key="i"
                :class="['x-video-poptip-item', {active: i===statusCtrl.videoUrlActiveIndex}]"
                @click="urlItemClick(v,i)"
              >{{v.label}}</div>
            </x-video-poptip>
          </div>
          <div
            v-show="videoActiveSubtitles.length"
            :class="`${prefixCls}__toolsbar_subtitles`"
          >
            <span class="label" @click.stop="togglePoptip('subtitles')">
              {{videoActiveSubtitle.label || '字幕'}}
            </span>
            <x-video-poptip v-show="statusCtrl.poptipActive==='subtitles'">
              <div
                v-for="(v,i) in videoActiveSubtitles" :key="i"
                :class="['x-video-poptip-item', {active: i===statusCtrl.videoSubtitleActiveIndex}]"
                @click="subtitleItemClick(v,i)"
              >{{v.label}}</div>
            </x-video-poptip>
          </div>
          <div :class="`${prefixCls}__toolsbar_spend`">
            <span class="label" @click.stop="togglePoptip('spendlist')">
              {{(playSpendList[statusCtrl.playSpendActiveIndex] || {}).label || '速度'}}
            </span>
            <x-video-poptip v-show="statusCtrl.poptipActive==='spendlist'">
              <div
                v-for="(v,i) in playSpendList" :key="i"
                :class="['x-video-poptip-item', {active: i===statusCtrl.playSpendActiveIndex}]"
                @click="spendItemClick(v,i)"
              >{{v.label}}</div>
            </x-video-poptip>
          </div>
          <div :class="`${prefixCls}__toolsbar_duration`">
            {{statusCtrl.videoCurrentTime | formatTime}} / {{statusCtrl.videoDuration | formatTime}}
          </div>
        </div>
        <div :class="`${prefixCls}__toolsbar_progress`">
          <x-video-progress ref="videoProgress" class="x-video-progress" @change="videoProgressChange"></x-video-progress>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
import xVideoProgress from './progress.vue'
import xVideoPoptip from './poptip.vue'
import {runPrefixMethod, onPrefixEvent, offPrefixEvent, deepCopy, debounce} from '@/script/utils.js'
const prefixCls = 'x-video'
const axios = require('axios')
export default {
  name: 'x-video',
  components: {
    xVideoProgress,
    xVideoPoptip
  },
  props: {
    size: {
      type: String,
      default: 'default' // default|large|small
    },
    options: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      prefixCls: prefixCls,
      statusCtrl: {
        collapsePlaylist: true,       // 折叠播放列表
        poptipActive: '',             // 当前展示的弹窗（音量调节器/播放速度/清晰度/字幕）
        isPlaying: false,             // 正在播放
        isLoading: false,             // 正在加载
        isFullscreen: false,          // 是否全屏
        fullscreenable: true,         // 是否允许全屏切换
        fullscreenActiveValue: 0,     // 当前视频全屏方式Value
        videoDuration: 0,             // 视频时长
        videoCurrentTime: 0,          // 当前进度
        videoActiveIndex: -1,         // 当前视频序号
        videoUrlActiveIndex: -1,      // 当前视频地址序号
        videoSubtitleActiveIndex: -1, // 当前视频字幕序号
        videoStartTime: 0,            // 视频开始时间
        videoVolume: 1,               // 视频音量
        playSpendActiveIndex: 0,      // 播放速度序号
        playOrderActive: 0,           // 播放顺序
        playOrderTextShow: false,     // 播放顺序文本显现
        playOrderTextTimer: null,     // 播放顺序文本显现计时器
        toolsbarShow: false,          // 控制条显现
        toolsbarTimer: null,          // 控制条显现计时器
        preload: 'auto',              // 预加载
        autoplay: false,              // 自动播放
        autoHideToolsbar: false,      // 自动隐藏控制条
        currentSrc: '',               // 当前视频地址
        showMenu: 'auto',             // 是否显示播放列表
        showMenuPoster: false,        // 是否显示播放列表poster
        showMenuDelete: false,        // 是否显示播放列表清空按钮
        error: false,                 // 播放出错
      },
      videoList: [
        // 视频列表
        // {
        //   label: 'name',        // 视频名称
        //   url: '',              // 视频地址
        //   urls: [               // 视频地址列表
        //     { label: '标清', value: '1', type: '' },
        //     { label: '高清', value: '2', type: '' },
        //     { label: '超清', value: '3', type: '' }
        //   ],
        //   duration: '',         // 视频时长
        //   poster: '',           // 视频封面
        //   subtitles: [          // 字幕列表
        //     { label: '中文', value: '', kind: 'subtitles', srclang: 'zh' },
        //     { label: '英文', value: '', kind: 'subtitles', srclang: 'en' }
        //   ]
        // }
      ],
      srtSubtitleData: [],
      localVideoList: [],
      playSpendList: [
        // 速度选项列表
        { label: '1.0x', value: 1.0 },
        { label: '1.5x', value: 1.5 },
        { label: '2.0x', value: 2.0 },
      ],
      playOrderList: [
        // 播放顺序列表
        { name: 'order', label: '顺序播放', value: 0, icon: 'xvu-order' },
        { name: 'loop', label: '列表循环', value: 1, icon: 'xvu-loop' },
        { name: 'loop-single', label: '单曲循环', value: 2, icon: 'xvu-loop-single' },
      ],
      fullscreenList: [
        // 全屏种类列表
        { name: 'winFullscreen', label: '全屏', value: 0, icons: ['xvu-app-maximum', 'xvu-app-restore'] },
        { name: 'webFullscreen', label: '网页全屏', value: 1, icons: ['xvu-web-maximum', 'xvu-web-restore'] }
      ]
    }
  },
  computed: {
    allVideoList () {
      return [...this.videoList, ...this.localVideoList]
    },
    localVideoSign () {
      let result = []
      this.localVideoList.forEach(v => {
        result.push([v.label, v.size, v.type, v.lastModified].join(';'))
      })
      return result
    },
    videoActive () {
      let result = this.allVideoList[this.statusCtrl.videoActiveIndex] || {}
      return result
    },
    videoActiveUrls () {
      let result = this.videoActive.urls || []
      return result
    },
    videoActiveSubtitles () {
      let result = deepCopy(this.videoActive.subtitles || this.options.subtitles || [])
      result.push({ label: '无字幕', value: '' })
      return result
    },
    videoActiveSubtitle () {
      let result = this.videoActiveSubtitles[this.statusCtrl.videoSubtitleActiveIndex] || {}
      result.value = result.value || ''
      result.kind = result.kind || 'subtitles'
      // 获取字幕文件后缀名
      let src = result.value.split('?')[0]
      let index = src.lastIndexOf('.')
      result.type = (index > -1) ? src.substring(index + 1) : ''
      return result
    },
    videoActiveType () {
      let result = 'video/mp4'
      let urlItem = this.videoActiveUrls[this.statusCtrl.videoUrlActiveIndex] || {}
      result = urlItem.type || this.videoActive.type || result
      return result
    },
    playOrderActive () {
      let result = this.playOrderList[this.statusCtrl.playOrderActive] || {}
      return result
    },
    fullscreenActive () {
      let result = { name: '', label: '', value: -1, icons: [] }
      this.fullscreenList.forEach(v => {
        if (v.value === this.statusCtrl.fullscreenActiveValue) {
          result = v
        }
      })
      return result
    },
    fullscreenListActive () {
      return this.fullscreenList.filter(v => v.value !== this.statusCtrl.fullscreenActiveValue)
    },
    showMenu () {
      let result = this.statusCtrl.showMenu
      if (this.statusCtrl.showMenu === 'auto') {
        result = (this.allVideoList.length > 1)
      }
      return result
    }
  },
  filters: {
    // 秒转时分秒
    formatTime (time) {
      let h = Math.floor(time / 3600) < 10 ? '0' + Math.floor(time / 3600) : Math.floor(time / 3600)
      let m = Math.floor((time / 60 % 60)) < 10 ? '0' + Math.floor((time / 60 % 60)) : Math.floor((time / 60 % 60))
      let s = Math.floor((time % 60)) < 10 ? '0' + Math.floor((time % 60)) : Math.floor((time % 60))
      time = (isNaN(h) || isNaN(m) || isNaN(s)) ? `--:--:--` : `${h}:${m}:${s}`
      return time
    }
  },
  watch: {
    options: {
      handler (n, o) {
        console.log(n, o)
        this.mergeVideoOptions(n)
      },
      deep: true,
      immediate: true
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.init()
    })
  },
  beforeDestroy () {
    this.close()
  },
  methods: {
    init () {
      // 控制条弹窗
      document.addEventListener('click', this.hidePoptip)
      // 全屏
      let val = runPrefixMethod(document, 'FullScreen') || runPrefixMethod(document, 'IsFullScreen')
      this.$set(this.statusCtrl, 'isFullscreen', val)
      onPrefixEvent(document, 'fullscreenchange', this.fullscreenChange)
      // 音量初始化
      if (this.$refs.video && this.$refs.volumebarProgress) {
        let volume = parseInt(this.options['volume'])
        if (isNaN(volume)) {
          volume = parseInt(localStorage.getItem('x-video-volume')) || 1
        }
        this.$set(this.statusCtrl, 'videoVolume', volume)
        this.$refs.video.volume = volume
        this.$refs.volumebarProgress.setRate(volume / 1)
      }
      // 自动播放
      if (this.allVideoList.length === 0) return
      if (this.statusCtrl.autoplay) {
        this.playItem(0)
      } else {
        this.switchItem(0)
      }
    },
    mergeVideoOptions (data) {
      Object.keys(data).forEach(k => {
        let target = ''
        switch (k) {
          case 'volume':
            target = parseInt(data[k])
            !isNaN(target) && this.$set(this.statusCtrl, 'videoVolume', target)
            break
          case 'preload':
          case 'autoplay':
          case 'autoHideToolsbar':
          case 'showMenu':
          case 'showMenuPoster':
          case 'showMenuDelete':
          case 'fullscreenable':
            this.$set(this.statusCtrl, k, data[k])
            break
          case 'videoList':
            this.statusCtrl.videoActiveIndex = -1
            this[k] = deepCopy(data[k] || [])
            this.switchItem(0)
            break
          case 'playSpendList':
            this[k] = deepCopy(data[k] || [])
            break
          case 'url':
            this.$set(this.statusCtrl, 'currentSrc', data[k] || '')
            break
        }
      })
    },
    // 键盘事件
    keydownHandler (e) {
      let keyCode = e.keyCode || e.which || e.charCode
      if (!this.$refs.video) return
      if (keyCode === 32) {
        // 空格
        this.togglePlay()
      } else if (keyCode === 37) {
        // left
        let target = Math.max(this.statusCtrl.videoCurrentTime - 10, 0)
        this.$refs.video.currentTime = target || 0
      } else if (keyCode === 39) {
        // right
        let target = Math.min(this.statusCtrl.videoCurrentTime + 10, this.statusCtrl.videoDuration)
        this.$refs.video.currentTime = target || 0
      }
    },
    // 图片错误处理
    onImgError (e) {
      let target = e.target || e.srcElement
      target.classList.add('error')
    },
    // 拖拽添加视频列表
    drop2playlistHandler (e) {
      let files = e.dataTransfer.files
      if (!files) return
      let localVideoList = [...this.localVideoList]
      for (let i = 0; i < files.length; i++) {
        let file = files[i]
        // 文件类型不存在即认为是文件夹或特殊文件
        if (file.type && /(.mp4|.webm|.ogg)$/i.test(file.name)) {
          window.URL = window.URL || window.webkitURL
          let url = window.URL.createObjectURL(file)
          // 去重
          let sign = [file.name, file.size, file.type, file.lastModified].join(';')
          if (!this.localVideoSign.includes(sign)) {
            localVideoList.push({
              label: file.name,
              url,
              size: file.size,
              type: file.type,
              lastModified: file.lastModified
            })
          }
        }
      }
      // 排序
      localVideoList.sort((a, b) => {
        if (a.label > b.label) return 1
        else if (a.label === b.label) return 0
        else if (a.label < b.label) return -1
      })
      this.localVideoList = localVideoList
    },
    // 显示/隐藏底部工具条
    toolsbarToggle: debounce(function () {
      if (!this.statusCtrl.autoHideToolsbar) {
        this.$set(this.statusCtrl, 'toolsbarShow', true)
        return
      }
      clearTimeout(this.statusCtrl.toolsbarTimer)
      this.$set(this.statusCtrl, 'toolsbarShow', true)
      this.statusCtrl.toolsbarTimer = setTimeout(() => {
        this.$set(this.statusCtrl, 'toolsbarShow', false)
      }, 3000)
    }, 150),
    // 展开/收起播放列表
    menuBtnClick () {
      this.$set(this.statusCtrl, 'collapsePlaylist', !this.statusCtrl.collapsePlaylist)
    },
    // 清空播放列表
    menuDeleteClick () {
      this.pause()
      this.pauseCallback()
      this.$set(this.statusCtrl, 'videoDuration', 0)
      this.$set(this.statusCtrl, 'videoCurrentTime', 0)
      this.$set(this.statusCtrl, 'videoActiveIndex', -1)
      this.$set(this.statusCtrl, 'videoUrlActiveIndex', -1)
      this.$set(this.statusCtrl, 'videoSubtitleActiveIndex', -1)
      this.$set(this.statusCtrl, 'currentSrc', '')
      this.localVideoList = []
      this.videoList = []
      this.$refs.videoProgress && this.$refs.videoProgress.setRate(0)
    },
    // 切换播放顺序
    playOrderChange () {
      clearTimeout(this.statusCtrl.playOrderTextTimer)
      this.$set(this.statusCtrl, 'playOrderActive', (this.statusCtrl.playOrderActive + 1) % this.playOrderList.length)
      this.$set(this.statusCtrl, 'playOrderTextShow', true)
      this.statusCtrl.playOrderTextTimer = setTimeout(() => {
        this.$set(this.statusCtrl, 'playOrderTextShow', false)
      }, 3000)
    },
    // 切换视频清晰度
    urlItemClick (item, index) {
      this.$set(this.statusCtrl, 'videoUrlActiveIndex', index)
      this.$set(this.statusCtrl, 'currentSrc', item.value || '')
    },
    // 切换视频字幕
    subtitleItemClick (item, index) {
      if (index === this.statusCtrl.videoSubtitleActiveIndex) return
      this.srtSubtitleData = []
      this.$set(this.statusCtrl, 'videoSubtitleActiveIndex', index)
      if (this.videoActiveSubtitle.type === 'srt') this.srtSubtitleLoad(item.value)
    },
    // 加载srt字幕
    srtSubtitleLoad (src) {
      axios.get(src).then((res) => {
        let dataArr1 = (res.data || '').split(/\r\n\r\n/)
        let dataArr2 = (res.data || '').split(/\n\s\n/)
        let dataArr3 = (res.data || '').split(/\n\n/)
        let dataArr = (dataArr1.length > dataArr2.length ? dataArr1 : dataArr2)
        dataArr = (dataArr.length > dataArr3.length ? dataArr : dataArr3)
        this.srtSubtitleData = dataArr
          .filter(item => !!item)
          .map((item, index) => {
            let textItem = item.split(/\n/)
            return {
              index,
              sort: textItem[0],
              timeLine: textItem[1],
              text: textItem.slice(2).join('<br />'),
              startTime: this.time2seconds(textItem[1].split(' --> ')[0]),
              endTime: this.time2seconds(textItem[1].split(' --> ')[1])
            }
          })
      })
    },
    // hh:mm:ss,xxx 转 seconds
    time2seconds (time) {
      let result = 0
      let arr = time.split(':')
      let factors = [3600, 60, 1]
      arr.forEach((v, i) => {
        result += (parseFloat(v.replace(',', '.')) * factors[i])
      })
      return result
    },
    // 切换播放速度
    spendItemClick (item, index) {
      if (!this.$refs.video) return
      this.$refs.video.playbackRate = item.value || 1
      this.$set(this.statusCtrl, 'playSpendActiveIndex', index)
    },
    // 切换全屏
    toggleFullscreen () {
      if (!this.$refs.xVideo) return
      if (this.fullscreenActive.name === 'webFullscreen') {
        this.$set(this.statusCtrl, 'isFullscreen', !this.statusCtrl.isFullscreen)
        this.$nextTick(() => {
          this.$refs.videoProgress && this.$refs.videoProgress.init()
        })
      } else if (this.fullscreenActive.name === 'winFullscreen') {
        if (this.statusCtrl.isFullscreen) {
          if (runPrefixMethod(document, 'CancelFullScreen')
          || runPrefixMethod(document, 'ExitFullScreen')) {
            this.$set(this.statusCtrl, 'isFullscreen', false)
          }
        } else if (runPrefixMethod(this.$refs.xVideo, 'RequestFullScreen')) {
          this.$set(this.statusCtrl, 'isFullscreen', true)
        }
      }
    },
    fullscreenChange () {
      let result = !!(runPrefixMethod(document, 'FullscreenElement')
      || runPrefixMethod(document, 'FullScreen')
      || runPrefixMethod(document, 'IsFullScreen'))
      this.$set(this.statusCtrl, 'isFullscreen', result)
      this.$nextTick(() => {
        this.$refs.videoProgress && this.$refs.videoProgress.init()
      })
    },
    // 切换全屏方式
    fullscreenItemClick (item, index) {
      console.log(item, index)
      this.$set(this.statusCtrl, 'fullscreenActiveValue', item.value || 0)
      this.toggleFullscreen()
    },
    // 显示/隐藏poptip
    togglePoptip (name) {
      let target = ''
      switch (name) {
        case 'volumebar':
          if (this.statusCtrl.poptipActive === name) {
            target = this.statusCtrl.videoVolume ? 0 : 1
            this.volumebarProgressChange(target)
            this.$refs.volumebarProgress && this.$refs.volumebarProgress.setRate(target)
          } else {
            this.$set(this.statusCtrl, 'poptipActive', name)
            this.$nextTick(() => {
              this.$refs.volumebarProgress.show()
            })
          }
          break
        case 'clarity':
        case 'subtitles':
        case 'spendlist':
          target = (this.statusCtrl.poptipActive === name) ? '' : name
          this.$set(this.statusCtrl, 'poptipActive', target)
          break
        default:
          this.$set(this.statusCtrl, 'poptipActive', name || '')
          break
      }
    },
    hidePoptip () {
      this.$set(this.statusCtrl, 'poptipActive', '')
    },
    // 视频音量调节
    volumebarProgressChange (rate) {
      if (!this.$refs.video) return
      let target = parseFloat((rate * 1).toFixed(2))
      this.$refs.video.volume = target
      this.$set(this.statusCtrl, 'videoVolume', target)
      localStorage.setItem('x-video-volume', target)
    },
    // 调整播放位置
    videoProgressChange (rate) {
      if (!this.$refs.video) return
      let target = Math.ceil(rate * this.statusCtrl.videoDuration)
      this.$refs.video.currentTime = target || 0
      this.$set(this.statusCtrl, 'videoCurrentTime', target || 0)
    },
    // 切换到指定视频
    switchItem (index) {
      let vItem = this.allVideoList[index]
      if (!vItem || (this.statusCtrl.videoActiveIndex === index)) return
      this.pause()
      this.$set(this.statusCtrl, 'videoCurrentTime', 0)
      this.$set(this.statusCtrl, 'videoActiveIndex', index)
      if (vItem.urls && vItem.urls.length) {
        if (this.statusCtrl.videoUrlActiveIndex > vItem.urls.length - 1) {
          this.$set(this.statusCtrl, 'videoUrlActiveIndex', 0)
        }
        this.$set(this.statusCtrl, 'currentSrc', (vItem.urls[this.statusCtrl.videoUrlActiveIndex] || {}).value || '')
      } else {
        this.$set(this.statusCtrl, 'currentSrc', vItem.url || '')
      }
      this.$refs.video.load()
    },
    // 播放指定视频
    playItem (index) {
      this.switchItem(index)
      this.$nextTick(() => {
        let value = (this.playSpendList[this.statusCtrl.playSpendActiveIndex] || {}).value || 1
        this.$refs.video && (this.$refs.video.playbackRate = value)
        this.play()
      })
    },
    // 播放/暂停
    togglePlay () {
      if (this.statusCtrl.isPlaying) this.pause()
      else this.play()
    },
    // 播放
    play () {
      if (this.$refs.video) {
        if (this.statusCtrl.error) {
          this.$set(this.statusCtrl, 'error', false)
          this.$refs.video.load()
        }
        let playPromise = this.$refs.video.play()
        if (playPromise !== undefined) {
          playPromise.then(() => {
          }).catch(()=> {
            this.pause()
            this.$set(this.statusCtrl, 'isLoading', false)
            this.$set(this.statusCtrl, 'error', true)
          })
        }
      }
    },
    // 暂停
    pause () {
      this.$refs.video && this.$refs.video.pause()
    },
    // 上一首
    prev () {
      let len = this.allVideoList.length
      let prevIndex = (this.statusCtrl.videoActiveIndex - 1 + len) % len
      this.playItem(prevIndex)
    },
    // 下一首
    next () {
      let len = this.allVideoList.length
      let nextIndex = (this.statusCtrl.videoActiveIndex + 1 + len) % len
      this.playItem(nextIndex)
    },
    // 关闭
    close () {
      this.pause()
      this.$set(this.statusCtrl, 'videoCurrentTime', 0)
      this.$set(this.statusCtrl, 'isLoading', false)
      this.statusCtrl.playOrderTextTimer = clearTimeout(this.statusCtrl.playOrderTextTimer)
      this.statusCtrl.toolsbarTimer = clearTimeout(this.statusCtrl.toolsbarTimer)
      document.removeEventListener('click', this.hidePoptip)
      offPrefixEvent(document, 'fullscreenchange', this.fullscreenChange)
    },
    // 播放事件·回调
    playCallback () {
      this.$set(this.statusCtrl, 'isPlaying', true)
      this.$set(this.statusCtrl, 'error', false)
    },
    // 暂停事件·回调
    pauseCallback () {
      this.$set(this.statusCtrl, 'isPlaying', false)
    },
    // 视频终止加载时触发·回调
    abortCallback () {
      this.$set(this.statusCtrl, 'isLoading', false)
    },
    // 当媒介能够开始播放时运行脚本·回调
    canplayCallback () {
      this.$set(this.statusCtrl, 'isLoading', false)
      this.$set(this.statusCtrl, 'error', false)
    },
    // 当媒介长度改变时运行脚本·回调
    durationchangeCallback (e) {
      let video = e.target || e.srcElement
      this.$set(this.statusCtrl, 'videoDuration', Math.ceil(video.duration))
      // 保存时长信息
      let len1 = this.videoList.length
      let len2 = this.localVideoList.length
      if (this.statusCtrl.videoActiveIndex < len1) {
        this.$set(this.videoList[this.statusCtrl.videoActiveIndex], 'duration', Math.ceil(video.duration))
      } else if (this.statusCtrl.videoActiveIndex < (len1 + len2)) {
        this.$set(this.localVideoList[this.statusCtrl.videoActiveIndex - len1], 'duration', Math.ceil(video.duration))
      }
    },
    // 当媒介改变其播放位置时运行脚本·回调
    timeupdateCallback (e) {
      let video = e.target || e.srcElement
      if (!video || !this.$refs.videoProgress) return
      this.$set(this.statusCtrl, 'videoCurrentTime', Math.ceil(video.currentTime) || 0)
      let target = this.statusCtrl.videoCurrentTime / this.statusCtrl.videoDuration
      this.$refs.videoProgress.setRate(target)
    },
    // 当媒介已抵达结尾时运行脚本·回调
    endedCallback () {
      if (this.playOrderActive.name === 'loop') this.next()
      else if (this.playOrderActive.name === 'loop-single') this.play()
      else if (this.statusCtrl.videoActiveIndex < (this.allVideoList.length - 1)) this.next()
    },
    // 当媒介已停止播放但打算继续播放时运行脚本·回调
    waitingCallback () {
      this.$set(this.statusCtrl, 'isLoading', true)
    },
    // 当在元素加载期间发生错误时运行脚本·回调
    errorCallback () {
      this.$set(this.statusCtrl, 'error', true)
    },
    // 当媒介元素的持续时间以及其他媒介数据已加载时运行脚本·回调
    loadedmetadataCallback (e) {
      let video = e.target || e.srcElement
      this.$set(this.statusCtrl, 'videoDuration', Math.ceil(video.duration))
    }
  }
}
</script>
